﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.DataModel;
using YArchitech.HVAC;
using YArchitech.LIB;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class FireExtinguisherCommand : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			UIApplication application = commandData.Application;
			UIDocument activeUIDocument = application.ActiveUIDocument;
            Autodesk.Revit.DB.Document document = activeUIDocument.Document;
			Selection selection = activeUIDocument.Selection;
			if (commandData == null)
			{
				throw new System.ArgumentNullException();
			}
			List<ViewType> list = new List<ViewType>();
            list.Add((ViewType)1);
            list.Add((ViewType)2);
            list.Add((ViewType)4);
			if (!YJKRevitTools.ViewCheck(application.ActiveUIDocument, list))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			Transaction transaction = null;
			FireExtinguisherParam fireExtinguisherParam = new FireExtinguisherParam();
			try
			{
				HYEquipmentCommon hyequipmentCommon = new HYEquipmentCommon();
				SpaceFamilyDataReader spaceFamilyDataReader = new SpaceFamilyDataReader();
				FireExtinguisherCalulate fireExtinguisherCalulate = new FireExtinguisherCalulate(document, selection);
				FamilySymbol familySymbolById;
				for (;;)
				{
					DialogResult dialogResult = fireExtinguisherCalulate.ShowDialog();
					if (dialogResult == DialogResult.OK)
					{
						fireExtinguisherParam = fireExtinguisherCalulate.fireExtinguisherParam;
						familySymbolById = spaceFamilyDataReader.GetFamilySymbolById(fireExtinguisherParam.Id, "FireExtinguisher", document, BuiltInCategory.OST_MechanicalEquipment);
						if (familySymbolById != null)
						{
							break;
						}
					}
					else
					{
						if (dialogResult != DialogResult.Abort)
						{
							goto IL_B62;
						}
						transaction = new Transaction(document, "计算保护面积");
						transaction.Start();
						fireExtinguisherCalulate.GetProtectArea();
						transaction.Commit();
					}
				}
				ConnectHelper connectHelper = new ConnectHelper();
				double num = familySymbolById.GetParameter("模型线实际长度1").AsDouble();
				double num2 = num * fireExtinguisherParam.Scale;
				for (;;)
				{
					transaction = new Transaction(document, "布置灭火器");
					transaction.Start();
					ICollection<ElementId> allFamilyInstance = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_MechanicalEquipment);
					if (fireExtinguisherCalulate.layTerminalType == 1)
					{
						List<XYZ> list2 = new List<XYZ>();
						XYZ xyz = selection.PickPoint("选择一个点坐标，以这个点坐标为中心，布置单个或多个灭火器");
						XYZ origin = new XYZ(xyz.X, xyz.Y + (1.5 * num2 + num), xyz.Z);
						int count = fireExtinguisherParam.Count;
						if (count > 2 && count % 2 != 0)
						{
							list2.Add(xyz);
							for (int i = 1; i <= (count - 1) / 2; i++)
							{
								list2.Add(new XYZ(xyz.X + (double)i * num2, xyz.Y, xyz.Z));
								list2.Add(new XYZ(xyz.X - (double)i * num2, xyz.Y, xyz.Z));
							}
						}
						else if (count > 1 && count % 2 == 0)
						{
							for (int j = 1; j <= count / 2; j++)
							{
								list2.Add(new XYZ(xyz.X + ((double)j - 0.5) * num2, xyz.Y, xyz.Z));
								list2.Add(new XYZ(xyz.X - ((double)j - 0.5) * num2, xyz.Y, xyz.Z));
							}
						}
						else if (count == 1)
						{
							list2.Add(xyz);
						}
						if (list2 != null && list2.Count > 0)
						{
							connectHelper.LayFamilyInstance(list2, familySymbolById, document.ActiveView.GenLevel, 0, document);
							if (fireExtinguisherParam.IsLable)
							{
                                document.GetTextNode(document.ActiveView, origin, new XYZ(1.0, 0.0, 0.0), new XYZ(0.0, 1.0, 0.0), (double)StringTools.GetStringByteLength(fireExtinguisherParam.Mode) / 100.0, (TextAlignFlags)128, fireExtinguisherParam.Mode);
							}
						}
					}
					else if (fireExtinguisherCalulate.layTerminalType == 0)
					{
						List<Element> list3 = new List<Element>();
						ISelectionFilter selectionFilter = new EquipmentSelectionFilter();
						IList<Element> list4 = selection.PickElementsByRectangle(selectionFilter, "框选一个或多个消火栓");
						if (list4.Count > 0)
						{
							foreach (Element element in list4)
							{
								if ((element as FamilyInstance).Symbol.Family.Name.Contains("消火栓") || (element as FamilyInstance).Symbol.Family.Name.Contains("消防"))
								{
									list3.Add(element);
								}
							}
							if (list3.Count > 0)
							{
								List<string> list5 = new List<string>();
								foreach (Element element2 in list3)
								{
									List<XYZ> list6 = new List<XYZ>();
									XYZ point = (element2.Location as LocationPoint).Point;
									if (element2.GetParameter("宽度") == null)
									{
										if (!list5.Contains((element2 as FamilyInstance).Symbol.Family.Name))
										{
											list5.Add((element2 as FamilyInstance).Symbol.Family.Name);
										}
									}
									else
									{
										double num3 = 0.5 * element2.GetParameter("宽度").AsDouble();
										IList<Connector> hyelementConnector = connectHelper.GetYJKElementConnector(element2 as FamilyInstance, (Autodesk.Revit.DB.Domain)3);
										Connector connector = hyelementConnector[0];
										Connector connector2 = hyelementConnector[1];
										if (hyelementConnector[0].Origin.Z > hyelementConnector[1].Origin.Z)
										{
											connector = hyelementConnector[0];
											Connector connector3 = hyelementConnector[1];
										}
										else
										{
											connector = hyelementConnector[1];
											Connector connector4 = hyelementConnector[0];
										}
										XYZ xyz2 = -connector.CoordinateSystem.BasisX;
										XYZ xyz3 = point + num3 * xyz2;
										XYZ origin2 = xyz3 + (1.5 * num2 + num) * xyz2;
										int count2 = fireExtinguisherParam.Count;
										if (count2 > 2 && count2 % 2 != 0)
										{
											list6.Add(xyz3);
											for (int k = 1; k <= (count2 - 1) / 2; k++)
											{
												list6.Add(xyz3 + (double)k * num2 * connector.CoordinateSystem.BasisZ);
												list6.Add(xyz3 - (double)k * num2 * connector.CoordinateSystem.BasisZ);
											}
										}
										else if (count2 > 1 && count2 % 2 == 0)
										{
											for (int l = 1; l <= count2 / 2; l++)
											{
												list6.Add(xyz3 + ((double)l - 0.5) * num2 * connector.CoordinateSystem.BasisZ);
												list6.Add(xyz3 - ((double)l - 0.5) * num2 * connector.CoordinateSystem.BasisZ);
											}
										}
										else if (count2 == 1)
										{
											list6.Add(xyz3);
										}
										if (list6 != null && list6.Count > 0)
										{
											ElementSet elementSet = connectHelper.LayFamilyInstance(list6, familySymbolById, document.ActiveView.GenLevel, 0, document);
											if (fireExtinguisherParam.IsLable)
											{
                                                document.GetTextNode(document.ActiveView, origin2, connector.CoordinateSystem.BasisZ, connector.CoordinateSystem.BasisZ, (double)StringTools.GetStringByteLength(fireExtinguisherParam.Mode) / 100.0, (TextAlignFlags)128, fireExtinguisherParam.Mode);
											}
											document.Regenerate();
											double num4 = connector.CoordinateSystem.BasisZ.AngleTo(new XYZ(1.0, 0.0, 0.0));
											if (connector.CoordinateSystem.BasisZ.AngleTo(new XYZ(0.0, -1.0, 0.0)) > Math.PI*.5)
											{
												num4 = Math.PI*2 - num4;
											}
											foreach (object obj in elementSet)
											{
												Element element3 = (Element)obj;
												XYZ point2 = (element3.Location as LocationPoint).Point;
												Line line = Line.CreateBound(point2, new XYZ(point2.X, point2.Y, 1.0));
												ElementTransformUtils.RotateElement(document, element3.Id, line, num4);
											}
										}
									}
								}
								if (list5.Count > 0)
								{
									string text = "有下列不是盈建科标准的消火栓，故不能布置灭火器：\n";
									for (int m = 0; m < list5.Count; m++)
									{
										if (m >= 5)
										{
											text += "\n......";
											break;
										}
										text = text + "\n" + list5[m];
									}
									MessageBox.Show(text, "盈建科提示");
								}
							}
						}
					}
					ICollection<ElementId> allFamilyInstance2 = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_MechanicalEquipment);
					new List<ElementId>();
					foreach (ElementId item in allFamilyInstance.Intersect(allFamilyInstance2))
					{
						allFamilyInstance2.Remove(item);
					}
					AuxiliaryLineOperate auxiliaryLineOperate = new AuxiliaryLineOperate();
					int num5 = 1;
					foreach (ElementId elementId in allFamilyInstance2)
					{
						Element elementById = document.GetElementById(elementId);
						if (fireExtinguisherParam.Mode != "")
						{
							elementById.GetParameter("灭火器型号").Set(fireExtinguisherParam.Mode);
						}
						if (fireExtinguisherParam.JiBie != "")
						{
							elementById.GetParameter("灭火级别").Set(fireExtinguisherParam.JiBie);
						}
						if (fireExtinguisherParam.Agent != "")
						{
							elementById.GetParameter("灭火剂").Set(fireExtinguisherParam.Agent);
						}
						if (fireExtinguisherParam.SymbolName != "")
						{
							elementById.GetParameter("灭火器类型").Set(fireExtinguisherParam.SymbolName);
						}
						if (fireExtinguisherParam.Scale != 0.0)
						{
							elementById.GetParameter("缩放比例").Set(fireExtinguisherParam.Scale);
						}
						HYParametersSetting hyparametersSetting = new HYParametersSetting(application);
						Parameter parameter = elementById.GetParameter("保护半径");
						if (parameter == null)
						{
							hyparametersSetting.SetFireExtinguisherRudioShareParam();
							parameter = elementById.GetParameter("保护半径");
						}
						if (parameter != null)
						{
							parameter.Set(UnitConvert.CovertToAPI(fireExtinguisherParam.Radius * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
						}
						Parameter parameter2 = null;
						Parameter parameter3 = null;
						double num6 = 0.0;
						if (elementById.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM) != null)
						{
							parameter3 = elementById.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
						}
						else
						{
							Parameter parameter4 = elementById.GetParameter(BuiltInParameter.FAMILY_LEVEL_PARAM);
							if (parameter4 != null)
							{
								parameter4.Set(document.ActiveView.GenLevel.Id);
							}
						}
						if (parameter3 != null)
						{
							parameter3.Set(UnitConvert.CovertToAPI(fireExtinguisherParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
							num6 = parameter3.AsDouble();
						}
						if (num6 != UnitConvert.CovertToAPI(fireExtinguisherParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2))
						{
							if (elementById.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM) != null)
							{
								parameter2 = elementById.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
							}
							if (parameter2 != null)
							{
								parameter2.Set(UnitConvert.CovertToAPI(fireExtinguisherParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
							}
						}
                        if (fireExtinguisherParam.Range && document.ActiveView.ViewType != (ViewType)4)
						{
							document.Regenerate();
							auxiliaryLineOperate.DrawRangLine(elementById as FamilyInstance, UnitConvert.CovertToAPI(fireExtinguisherParam.Radius * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2), "", num5);
							num5++;
						}
					}
					document.Regenerate();
					transaction.Commit();
				}
				IL_B62:
				return Autodesk.Revit.UI.Result.Succeeded;
			}
            catch (Autodesk.Revit.Exceptions.OperationCanceledException ex)
			{
				ex.ToString();
			}
			catch (Exception ex2)
			{
				message = ex2.Message;
			}
			finally
			{
				if (transaction != null && transaction.GetStatus() != (TransactionStatus)3)
				{
					transaction.RollBack();
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}
	}
}
